﻿/*  ----------------------------------------------------------------------------
 *  Project Intercept
 *  ----------------------------------------------------------------------------
 *  System.Common
 *  ----------------------------------------------------------------------------
 *  File:        Hash.cs
 *  Authors:     Dremation
 *  ----------------------------------------------------------------------------
 *  GNU General Public License version 2 (GPLv2)
 */
using System;
using System.Security.Cryptography;
using System.Text;

namespace System.Common
{
    public class Hash
    {
        /// <summary>The wanted hash function.</summary>
        public enum HashType : int
        {
            /// <summary>MD5 Hashing</summary>
            MD5,
            /// <summary>SHA1 Hashing</summary>
            SHA1,
            /// <summary>SHA256 Hashing</summary>
            SHA256,
            /// <summary>SHA384 Hashing</summary>
            SHA384,
            /// <summary>SHA512 Hashing</summary>
            SHA512
        } /* HashType */

        /// <summary>Generates the hash of a text.</summary>
        /// <param name="strPlain">The text of which to generate a hash of.</param>
        /// <param name="hshType">The hash function to use.</param>
        /// <returns>The hash as a hexadecimal string.</returns>
        public static string GetHash(string strPlain, HashType hshType)
        {
            string strRet;
            switch (hshType)
            {
                case HashType.MD5: strRet = GetMD5(strPlain); break;
                case HashType.SHA1: strRet = GetSHA1(strPlain); break;
                case HashType.SHA256: strRet = GetSHA256(strPlain); break;
                case HashType.SHA384: strRet = GetSHA384(strPlain); break;
                case HashType.SHA512: strRet = GetSHA512(strPlain); break;
                default: strRet = "Invalid HashType"; break;
            }
            return strRet;
        } /* GetHash */

        /// <summary>Checks a text with a hash.</summary>
        /// <param name="strOriginal">The text to compare the hash against.</param>
        /// <param name="strHash">The hash to compare against.</param>
        /// <param name="hshType">The type of hash.</param>
        /// <returns>True if the hash validates, false otherwise.</returns>
        public static bool CheckHash(string strOriginal, string strHash, HashType hshType)
        {
            string strOrigHash = GetHash(strOriginal, hshType);
            return (strOrigHash == strHash);
        } /* CheckHash */

        private static string GetMD5(string strPlain)
        {
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(strPlain);
            MD5 md5 = new MD5CryptoServiceProvider();
            string strHex = "";

            HashValue = md5.ComputeHash(MessageBytes);
            foreach (byte b in HashValue)
            {
                strHex += String.Format("{0:x2}", b);
            }
            return strHex;
        } /* GetMD5 */

        private static string GetSHA1(string strPlain)
        {
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(strPlain);
            SHA1Managed SHhash = new SHA1Managed();
            string strHex = "";

            HashValue = SHhash.ComputeHash(MessageBytes);
            foreach (byte b in HashValue)
            {
                strHex += String.Format("{0:x2}", b);
            }
            return strHex;
        } /* GetSHA1 */

        private static string GetSHA256(string strPlain)
        {
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(strPlain);
            SHA256Managed SHhash = new SHA256Managed();
            string strHex = "";

            HashValue = SHhash.ComputeHash(MessageBytes);
            foreach (byte b in HashValue)
            {
                strHex += String.Format("{0:x2}", b);
            }
            return strHex;
        } /* GetSHA256 */

        private static string GetSHA384(string strPlain)
        {
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(strPlain);
            SHA384Managed SHhash = new SHA384Managed();
            string strHex = "";

            HashValue = SHhash.ComputeHash(MessageBytes);
            foreach (byte b in HashValue)
            {
                strHex += String.Format("{0:x2}", b);
            }
            return strHex;
        } /* GetSHA384 */

        private static string GetSHA512(string strPlain)
        {
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] HashValue, MessageBytes = UE.GetBytes(strPlain);
            SHA512Managed SHhash = new SHA512Managed();
            string strHex = "";

            HashValue = SHhash.ComputeHash(MessageBytes);
            foreach (byte b in HashValue)
            {
                strHex += String.Format("{0:x2}", b);
            }
            return strHex;
        } /* GetSHA512 */

    }
}
